using MediatR;
using RBAC.ErrorCode;
using RBAC.Write.Api.Application.Command.ERP.PurchasingManagement.PurchaseInvoicefolder;
using Microsoft.Extensions.Logging;
using RBAC.Domain.WarehouseManagement;
using System;
using System.Linq;
using System.Transactions;
using RBAC.Interstructrue.Base;
using Dapper;
using System.Text.Json;

namespace RBAC.Write.Api.Application.Handler.ERP.PurchasingManagement.PurchaseInvoicefolder
{
    public class AddPurchaseInvoiceCommandHandler : IRequestHandler<AddPurchaseInvoiceCommands, APIResult<int>>
    {
        private readonly ILogger<AddPurchaseInvoiceCommandHandler> _logger;
        private readonly IBaseRepository<PurchaseInvoice> _invoiceRepository;
        private readonly IDbConnectionFactory _connectionFactory;

        public AddPurchaseInvoiceCommandHandler(
            ILogger<AddPurchaseInvoiceCommandHandler> logger,
            IBaseRepository<PurchaseInvoice> invoiceRepository,
            IDbConnectionFactory connectionFactory)
        {
            _logger = logger;
            _invoiceRepository = invoiceRepository;
            _connectionFactory = connectionFactory;
        }

        public Task<APIResult<int>> Handle(AddPurchaseInvoiceCommands request, CancellationToken cancellationToken)
        {
            var result = new APIResult<int>();

            if (request == null || request.Invoice == null)
            {
                result.Code = APIEnums.Fail;
                result.Msg = "参数不能为空";
                result.Data = 0;
                return Task.FromResult(result);
            }

            try
            {
                var invoice = request.Invoice;

                // 基础校验（可按需扩展）
                if (string.IsNullOrWhiteSpace(invoice.DocumentCode))
                {
                    result.Code = APIEnums.Fail;
                    result.Msg = "单据编码不能为空";
                    result.Data = 0;
                    return Task.FromResult(result);
                }

                using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    // 设置基础字段（如 BaseEntity 中的字段）
                    invoice.CreateTime = DateTime.Now;
                    invoice.IsDeleted = false;

                    // 1. Dapper 仓储新增主表，返回自增ID
                    var newId = _invoiceRepository.Create(invoice);
                    if (newId <= 0)
                    {
                        throw new InvalidOperationException("新增采购发票失败，返回的ID无效");
                    }

                    // 2. Dapper 原生批量插入物料（如有）
                    if (request.Materials != null && request.Materials.Any())
                    {
                        using var conn = _connectionFactory.CreateConnectionWithRetry();
                        // 为每条明细设置外键
                        foreach (var m in request.Materials)
                        {
                            m.PurchaseInvoiceId = newId;
                        }

                        // 调试日志：确认参数赋值
                        try
                        {
                            var sample = request.Materials.FirstOrDefault();
                            _logger.LogInformation("AddPurchaseInvoice: newId={NewId}, firstMaterial={Material}", newId, sample != null ? JsonSerializer.Serialize(sample) : "null");
                        }
                        catch (Exception logEx)
                        {
                            _logger.LogWarning(logEx, "日志序列化物料失败");
                        }

                        const string insertSql = @"INSERT INTO ProcurementMaterials
                            (PurchaseInvoiceId, PurchaseOrderNumber, Warehouse, InboundOrderNumber, MaterialCode, MaterialName, ModelSpecifications, MainMeasurement, `Number`, UnitPrice, Amount, TaxRate, TaxAmount, PriceTaxTotal, IsDel)
                            VALUES
                            (@PurchaseInvoiceId, @PurchaseOrderNumber, @Warehouse, @InboundOrderNumber, @MaterialCode, @MaterialName, @ModelSpecifications, @MainMeasurement, @Number, @UnitPrice, @Amount, @TaxRate, @TaxAmount, @PriceTaxTotal, @IsDel);";

                        // 批量执行
                        var affected = conn.Execute(insertSql, request.Materials);
                        if (affected != request.Materials.Count)
                        {
                            throw new InvalidOperationException($"批量新增物料失败：预期 {request.Materials.Count} 条，实际 {affected} 条");
                        }
                    }

                    scope.Complete();

                    result.Code = APIEnums.Success;
                    result.Msg = "新增成功";
                    result.Data = newId;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "新增采购发票失败: {Message}", ex.Message);
                result.Code = APIEnums.Fail;
                result.Msg = "新增失败：" + ex.Message;
                result.Data = 0;
            }

            return Task.FromResult(result);
        }
    }
}
